package org.activequant.core.domainmodel.data;

import static org.activequant.util.tools.IdentityUtils.equalsTo;
import static org.activequant.util.tools.IdentityUtils.safeCompare;
import static org.activequant.util.tools.IdentityUtils.safeHashCode;

import java.io.Serializable;

import org.activequant.core.types.TimeStamp;

/**
 * Represents a market parameter.
 * <br>
 * A MarketDataEntity subclass. Defines the Type enum (which has 1 value: NEWS). Holds the following associated variables:
 * <ul>
 * <li>key(String)</li>
 * <li>value(String)</li>
 * <li>type(Type)</li>
 * </ul>
 * And the following inherited variables:
 * <ul>
 * <li>id(Long)</li>
 * <li>instrumentSpecification(InstrumentSpecification)</li>
 * <li>timeStamp(TimeStamp)</li>
 * </ul>
 * <b>History:</b><br>
 *  - [05.12.2007] Created (Erik Nijkamp)<br>
 *  - [07.01.2008] Fixing typo (Ulrich Staudinger)<br>
 *  - [13.01.2008] Extending MarketDataEntity (Erik Nijkamp)<br>
 *
 *  @author Erik Nijkamp
 *  @author Ulrich Staudinger
 */
public class MarketParameter extends MarketDataEntity<MarketParameter> implements Serializable {
	
	private static final long serialVersionUID = -1112863276595579381L;
	/**
	 * An enum type with 1 value: NEWS
	 * @author Dimitar
	 *
	 */
	public enum Type { NEWS };
	/**
	 * private String key;
	 */
	private String key;
	/**
	 * private String value;
	 */
	private String value;
	/**
	 * private Type type;
	 */
	private Type type;
	/**
	 * constructs a MarketParameter(MarketDataEntity subclass) using the given stamp(TimeStamp) to set its associated/inherited timeStamp(TimeStamp).<br/>
	 * The given key(String) and value(String) are used to set its associated key(String) and value(String).
	 * @param stamp
	 * @param key
	 * @param value
	 */
	public MarketParameter(TimeStamp stamp, String key, String value) {
		super(stamp);
		this.key = key;
		this.value = value;
	}
	/**
	 * returns the associated key(String)
	 * @return
	 */
	public String getKey() {
		return key;
	}
	/**
	 * sets the associated key(String) with the given key(String)
	 * @param key
	 */
	public void setKey(String key) {
		this.key = key;
	}
	/**
	 * returns the associated value(String)
	 * @return
	 */
	public String getValue() {
		return value;
	}
	/**
	 * sets the associated value(String) with the given value(String)
	 * @param value
	 */
	public void setValue(String value) {
		this.value = value;
	}

	@Override
	public MarketParameter clone() {
		return new MarketParameter(getTimeStamp(), key, value);
	}
	/**
	 * returns the associated type(Type) enum
	 * @return
	 */
	public Type getType() {
		return type;
	}
	/**
	 * sets the associated type(Type) enum with the given type(Type) enum
	 * @param type
	 */
	public void setType(Type type) {
		this.type = type;
	}
	
    /**
     * {@inheritDoc}
     */
	public int compareTo(MarketParameter other) {
		// ATTENTION: keep in sync with hashCode();
		int rc;
		
		if((rc = safeCompare(getInstrumentSpecification(), other.getInstrumentSpecification())) != 0) {
			return rc;
		}
		if((rc = safeCompare(this.getTimeStamp(), other.getTimeStamp())) != 0) {
			return rc;
		}
		if((rc = safeCompare(this.key, other.key)) != 0) {
			return rc;
		}
		if((rc = safeCompare(this.value, other.value)) != 0) {
			return rc;
		}
		if((rc = safeCompare(this.type, other.type)) != 0) {
			return rc;
		}
		return 0;
	}
    
    /**
     * {@inheritDoc}
     */
    @Override
	public int hashCode() {
		// ATTENTION: keep in sync with comapreTo();
        return safeHashCode(getInstrumentSpecification())
        	+ safeHashCode(this.getTimeStamp())
        	+ safeHashCode(this.key)
        	+ safeHashCode(this.value)
        	+ safeHashCode(this.type);
	}
	
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object other) {
    	// NOTE: delegates to compareTo()
    	return equalsTo(this, other);
	}

}
